﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;

namespace BasicMVVMCommand
{
    public class LoginViewModel : INotifyPropertyChanged 
    {
        public LoginViewModel()
        {
            eventListener.RegisterListener(typeof(INPCManager), 
                new EventHandler (_user_PropertyChanged));
        } 
        UserLogin _user;

        INPCManager listener; 
        public UserLogin User
        {
            get
            {
                return _user; 
            }
            set
            {                
#if !USERELAY      
                //For the record, I am not saying this is good.. I am merely 
                // demonstrating that DelegateCommand is more work than RelayCommand. 
                if (_user != null && _user is INotifyPropertyChanged)
                {
                    INPCManager.RemoveListener(_user, eventListener);
                }

                if (value != null && value is INotifyPropertyChanged)
                    INPCManager.AddListener(value, eventListener);                                                                           
                 
#endif          
      
                _user = value;
                OnPropertyChanged("User");

            } 
        }

        GenericListener eventListener = new GenericListener(); 

        void _user_PropertyChanged(object sender, EventArgs unused)
        {
            if (_loginCommand != null && _loginCommand is DelegateCommand<object>)
            {
                DelegateCommand<object> cmd = _loginCommand as DelegateCommand<object>;
                cmd.RaiseCanExecuteChanged(); 

            } 
        }

        private ICommand _loginCommand;

        public ICommand LoginCommand
        {
            get {

#if USERELAY 
                if (_loginCommand == null)
                    _loginCommand = new RelayCommand(OnLoginExecuted, OnLoginCanExecute); 
#else 
                if (_loginCommand == null)
                    _loginCommand = new DelegateCommand<object> (OnLoginExecuted, OnLoginCanExecute); 
#endif

                return _loginCommand; 
            }
           
        }

        protected void OnLoginExecuted(object param)
        {
            //this shows UI for demo purposes; usually there is some other 
            //presenter or mediator we would call to show UI..
            MessageBox.Show("executed"); 
        }

        protected bool OnLoginCanExecute(object param)
        {
            System.Diagnostics.Debug.WriteLine("Can execute called"); 
            if ( User != null ) 
            { 
                return !( string.IsNullOrEmpty(User.Login) || 
                       string.IsNullOrEmpty (User.Password )); 
            } 
            return  false ;                 
        } 
       

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler ph = this.PropertyChanged;
            if (ph != null)
            {
                ph(this, new PropertyChangedEventArgs(name));
            }
        }


        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
